package jp.cane.android.luciferblue;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import jp.cane.android.luciferblue.MainService.MainServiceListener;
import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.WindowManager;
import android.widget.TextView;

public class MainActivity extends FragmentActivity implements
		ActionBar.TabListener, MainServiceListener {
	private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";
	final static private int FIRST = 0;

	final static private String POLLING_STRING = "polling_string";
	final static private String POLLING_INTERVAL = "polling_interval";
	final static private String POLLING_LOOP = "polling_loop";

	final static private String ECHO_SETTING = "echo_setting";

	final static private int REQUEST_POLLING_SETTING = 1;

	private Handler handler = new Handler();

	private RawFragment fragment_raw = new RawFragment();
	private DozeFragment fragment_doze = new DozeFragment();
	private CpmFragment fragment_cpm = new CpmFragment();
	private CoefFragment fragment_coef = new CoefFragment();

	protected static boolean echo = false;

	// 取得したServiceの保存
	private MainService mBoundService = null;

	private ServiceConnection mConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			// サービスとの接続確立時に呼び出される
			// サービスにはIBinder経由で#getService()してダイレクトにアクセス可能
			mBoundService = ((MainService.MainServiceBinder) service)
					.getService();
			mBoundService.addListener(MainActivity.this);

			// 必要であればmBoundServiceを使ってバインドしたサービスへの制御を行う
			fragment_raw.setService(mBoundService);
			fragment_doze.setService(mBoundService);
			fragment_cpm.setService(mBoundService);
			fragment_coef.setService(mBoundService);
		}

		public void onServiceDisconnected(ComponentName className) {
			// サービスとの切断(異常系処理)
			// プロセスのクラッシュなど意図しないサービスの切断が発生した場合に呼ばれる。
			mBoundService.removeListener(MainActivity.this);
			mBoundService = null;
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Keep screen on
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

		if (getIntent().getExtras() != null) {
			MainService.device = (BluetoothDevice) getIntent().getExtras().get(
					BluetoothDevice.EXTRA_DEVICE);
		}

		setContentView(R.layout.activity_main);

		Intent intent = new Intent(this, MainService.class);
		startService(intent);
		// サービスとの接続を確立する。明示的にServiceを指定
		// (特定のサービスを指定する必要がある。他のアプリケーションから知ることができない = ローカルサービス)
		bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

		// // Bluetooth を発見可能にする
		// Intent discoverableIntent = new Intent(
		// BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
		// discoverableIntent.putExtra(
		// BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
		// startActivity(discoverableIntent);

		// Set up the action bar.
		final ActionBar actionBar = getActionBar();
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

		// For each of the sections in the app, add a tab to the action bar.
		actionBar.addTab(actionBar.newTab().setText(R.string.title_raw)
				.setTabListener(this));
		actionBar.addTab(actionBar.newTab().setText(R.string.title_doze)
				.setTabListener(this));
		actionBar.addTab(actionBar.newTab().setText(R.string.title_cpm)
				.setTabListener(this));
		actionBar.addTab(actionBar.newTab().setText(R.string.title_coef)
				.setTabListener(this));

		new Timer(false).scheduleAtFixedRate(
				new TimerTask() {
					@Override
					public void run() {
						final Calendar calendar = Calendar.getInstance();

						@SuppressWarnings("unused")
						final int year = calendar.get(Calendar.YEAR);
						@SuppressWarnings("unused")
						final int month = calendar.get(Calendar.MONTH);
						@SuppressWarnings("unused")
						final int day = calendar.get(Calendar.DAY_OF_MONTH);
						final int hour = calendar.get(Calendar.HOUR_OF_DAY);
						final int minute = calendar.get(Calendar.MINUTE);
						final int second = calendar.get(Calendar.SECOND);
						@SuppressWarnings("unused")
						final int ms = calendar.get(Calendar.MILLISECOND);

						final String time = ""
								+ ("0" + hour)
										.substring(("0" + hour).length() - 2)
								+ ":"
								+ ("0" + minute).substring(("0" + minute)
										.length() - 2)
								+ ":"
								+ ("0" + second).substring(("0" + second)
										.length() - 2);

						handler.post(new Runnable() {
							public void run() {
								TextView text = (TextView) findViewById(R.id.time);
								text.setText(time);
							}
						});
					}
				}, new Date(
						(System.currentTimeMillis() + 1000 - 1) / 1000 * 1000),
				1000);

		SharedPreferences pref = PreferenceManager
				.getDefaultSharedPreferences(this);
		// 認証情報を復元
		MainService.username = pref.getString(AuthActivity.AUTH_USERNAME, "");
		MainService.password = pref.getString(AuthActivity.AUTH_PASSWORD, "");
		// POLLING 設定値を復元
		MainService.pollingStrings = pref.getString(POLLING_STRING, "");
		MainService.pollingInterval = pref.getInt(POLLING_INTERVAL, 1);
		MainService.pollingLoop = pref.getBoolean(POLLING_LOOP, false);
		// ECHO 設定値を復元
		echo = pref.getBoolean(ECHO_SETTING, false);
	}

	@Override
	protected void onDestroy() {
		unbindService(mConnection);
		super.onDestroy();
	}

	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == REQUEST_POLLING_SETTING && resultCode == RESULT_OK) {
			Bundle extras = data.getExtras();

			MainService.pollingStrings = (extras.getString("pollingStrings"));
			MainService.pollingInterval = (extras.getInt("pollingInterval"));
			MainService.pollingLoop = (extras.getBoolean("pollingLoop"));

			// POLLING 設定値が変更されたので、保存。
			SharedPreferences pref = PreferenceManager
					.getDefaultSharedPreferences(this);
			Editor edit = pref.edit();
			edit.putString(POLLING_STRING, MainService.pollingStrings);
			edit.putInt(POLLING_INTERVAL, MainService.pollingInterval);
			edit.putBoolean(POLLING_LOOP, MainService.pollingLoop);
			edit.commit();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		{
			MenuItem item = menu.add(0, FIRST, 0, R.string.scan);
			item.setOnMenuItemClickListener(new OnMenuItemClickListener() {
				public boolean onMenuItemClick(MenuItem item) {
					if (MainService.device == null) {
						// サーバーモード
						return true;
					}
					Intent intent = new Intent(MainActivity.this,
							DiscoveryActivity.class);
					startActivity(intent);
					finish();
					return true;
				}
			});
		}
		{
			MenuItem item = menu.add(0, FIRST + 1, 0, R.string.echo);
			item.setOnMenuItemClickListener(new OnMenuItemClickListener() {
				public boolean onMenuItemClick(MenuItem item) {
					MainActivity.echo = !MainActivity.echo;

					// ECHO 設定値を保存
					SharedPreferences pref = PreferenceManager
							.getDefaultSharedPreferences(MainActivity.this);
					Editor edit = pref.edit();
					edit.putBoolean(ECHO_SETTING, MainActivity.echo);
					edit.commit();

					return true;
				}
			});
		}
		{
			MenuItem item = menu.add(0, FIRST + 2, 0, R.string.setuppolling);
			item.setOnMenuItemClickListener(new OnMenuItemClickListener() {
				public boolean onMenuItemClick(MenuItem item) {
					Intent intent = new Intent(MainActivity.this,
							PollingActivity.class);
					intent.putExtra("pollingStrings",
							MainService.pollingStrings);
					intent.putExtra("pollingInterval",
							MainService.pollingInterval);
					intent.putExtra("pollingLoop", MainService.pollingLoop);
					startActivityForResult(intent, REQUEST_POLLING_SETTING);
					return true;
				}
			});
		}
		{
			MenuItem item = menu.add(0, FIRST + 3, 0, R.string.setupauth);
			item.setOnMenuItemClickListener(new OnMenuItemClickListener() {
				public boolean onMenuItemClick(MenuItem item) {
					Intent intent = new Intent(MainActivity.this,
							AuthActivity.class);
					startActivity(intent);
					return true;
				}
			});
		}
		{
			MenuItem item = menu.add(0, FIRST + 4, 0, R.string.startRegister);
			item.setOnMenuItemClickListener(new OnMenuItemClickListener() {
				public boolean onMenuItemClick(MenuItem item) {
					if (mBoundService != null) {
						mBoundService.startBackground();
					}
					return true;
				}
			});
		}
		{
			MenuItem item = menu.add(0, FIRST + 5, 0, R.string.stopRegister);
			item.setOnMenuItemClickListener(new OnMenuItemClickListener() {
				public boolean onMenuItemClick(MenuItem item) {
					if (mBoundService != null) {
						mBoundService.stopBackground();
					}
					return true;
				}
			});
		}

		return true;
	}

	@Override
	public void onRestoreInstanceState(Bundle savedInstanceState) {
		if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
			getActionBar().setSelectedNavigationItem(
					savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
		}
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar()
				.getSelectedNavigationIndex());
	}

	public void onTabUnselected(ActionBar.Tab tab,
			FragmentTransaction fragmentTransaction) {
	}

	public void onTabSelected(ActionBar.Tab tab,
			FragmentTransaction fragmentTransaction) {
		// When the given tab is selected, show the tab contents in the
		// container
		Fragment fragment = null;
		switch (tab.getPosition()) {
		case 0:
			fragment = fragment_raw;
			break;
		case 1:
			fragment = fragment_doze;
			break;
		case 2:
			fragment = fragment_cpm;
			break;
		case 3:
			fragment = fragment_coef;
			break;
		default:
		}
		// Fragment fragment = new MainActivity();
		// Bundle args = new Bundle();
		// args.putInt(RawFragment.ARG_SECTION_NUMBER, tab.getPosition() + 1);
		// fragment1.setArguments(args);
		getSupportFragmentManager().beginTransaction()
				.replace(R.id.container, fragment).commit();

		fragment_raw.updateView();
		fragment_doze.change("");
		fragment_cpm.change("");
		fragment_coef.change("");
	}

	public void onTabReselected(ActionBar.Tab tab,
			FragmentTransaction fragmentTransaction) {
	}

	public void change(final String str) {
		if (mBoundService == null) {
			return;
		}
		{
			final Calendar calendar = mBoundService.getThread().lastReceivedTime;

			@SuppressWarnings("unused")
			final int year = calendar.get(Calendar.YEAR);
			@SuppressWarnings("unused")
			final int month = calendar.get(Calendar.MONTH);
			@SuppressWarnings("unused")
			final int day = calendar.get(Calendar.DAY_OF_MONTH);
			final int hour = calendar.get(Calendar.HOUR_OF_DAY);
			final int minute = calendar.get(Calendar.MINUTE);
			final int second = calendar.get(Calendar.SECOND);
			@SuppressWarnings("unused")
			final int ms = calendar.get(Calendar.MILLISECOND);

			// Log.v("year/month/day hour:minute:second", year + "/"
			// + (month + 1) + "/" + day + "/" + " " + hour + ":"
			// + minute + ":" + second + "." + ms);

			final String time = ""
					+ ("0" + hour).substring(("0" + hour).length() - 2) + ":"
					+ ("0" + minute).substring(("0" + minute).length() - 2)
					+ ":"
					+ ("0" + second).substring(("0" + second).length() - 2);

			handler.post(new Runnable() {
				public void run() {
					TextView text = (TextView) findViewById(R.id.lasttime);
					text.setText(time);
				}
			});
		}
		{
			ArrayList<Long> countList = mBoundService.getThread().countList;
			while (countList.size() > 0
					&& countList.get(0).longValue() < System
							.currentTimeMillis() - 5 * 60 * 1000) {
				countList.remove(0);
			}
		}
		this.fragment_raw.change(str);
		this.fragment_doze.change(str);
		this.fragment_cpm.change(str);
		this.fragment_coef.change(str);
	}
}
